import "./index.scss"
import { defineComponent, ref, computed, onMounted, onUnmounted, watch, nextTick } from "vue"
import { fetchEventSource } from "@microsoft/fetch-event-source"
import { ElMessageBox, ElMessage } from "element-plus"
import MarkdownIt from "markdown-it"
import "github-markdown-css"
import Clipboard from "clipboard"
import QuestionExample from "./components/questionExample.vue"
import { htmlToText } from "html-to-text"
import type { ChatItem } from "../../../types/chat"
import { getTokenApi } from "../../api/gptLogin/index"
import Agreement from "../../components/Agreement/index.vue"
import ViewDialog from "./components/viewDialog.vue"
import emitter from "../../utils/eventBus"
export default defineComponent({
  components: { QuestionExample, Agreement, ViewDialog },
  setup() {
    const inputValue = ref("")
    const preInputValue = ref("") //上一次查询输入内容,用于重新生成使用
    const isLoading = ref(false) //节流loading
    const loadingStatus = ref(false) //加载状态显示loading
    const chatList = ref<ChatItem[]>([])
    const contentItems = ref("") //当前正在输出的数据流
    const chatContainerRef = ref()
    const isRegenerate = ref(false) //是否重新生成
    const controller = ref()
    const signal = ref()
    const copyText = ref("") //复制的文字
    const copyIndex = ref<number>()
    const questionList = ref<string[]>([
      "再查查产品介绍？",
      "再查查有哪些功能？",
      "再查查的产品特性与优势？",
      "再查查的操作使用流程？",
      "尽职调查工作流程主要包括哪几个方面?"
    ]) //试问问题列表
    const token = ref("")
    const showList = ref(true) //是否展示试问问题
    const scrollTopShow = ref(false)
    const scrollBottomShow = ref(false)
    const sessionId = ref("")
    const isRolling = ref(false) //鼠标滚轮是否滚动
    const isBottom = ref(false) //滚动参数
    onMounted(() => {
      initFn()
      chatContainerRef.value.addEventListener("wheel", moveWheel)
      emitter.emit("custom-event", { data: false })
    })
    const getToken = () => {
      getTokenApi({
        grant_type: "client_credentials",
        client_id: "r3Aj2wrNd4IwTo5wDB7WOvtA",
        client_secret: "1eU8WcxQUzDKFw0nH7MgE4Y4iLBMgilU"
      }).then((res) => {
        token.value = res.access_token
      })
    }
    const showThinkFn = (index: number, answerIndex: number) => {
      chatList.value[index].showThinkList[answerIndex] = true
    }
    const hideThinkFn = (index: number, answerIndex: number) => {
      chatList.value[index].showThinkList[answerIndex] = false
    }
    // 处理鼠标滚轮事件
    const moveWheel1 = ref(true)
    const moveWheel2 = ref(false)
    const wheelClock = ref()
    function stopWheel() {
      if (moveWheel2.value == true) {
        // console.log("滚轮停止了")
        // isRolling.value = false
        moveWheel2.value = false
        moveWheel1.value = true
      }
    }
    function moveWheel() {
      if (moveWheel1.value == true) {
        // console.log("滚动了")
        isRolling.value = true
        moveWheel1.value = false
        moveWheel2.value = true
        //这里写开始滚动时调用的方法
        wheelClock.value = setTimeout(stopWheel, 200)
      } else {
        clearTimeout(wheelClock.value)
        wheelClock.value = setTimeout(stopWheel, 150)
      }
    }

    //初始化
    const initFn = () => {
      chatList.value = [
        // { type: "user", message: ["今天星期几"], answerIndex: 0, isLoading: false },
        // { type: "ai", message: ["星期一"], answerIndex: 0, isLoading: false },
        // {
        //   type: "user",
        //   message: [
        //     "今天星期几今天星期几今天星期几今天星期几今天星期几今天星期几今天星期几今天星期几今天星期几今天星期几今天星期几今天星期几今天星期几今天星期几今天星期几"
        //   ],
        //   answerIndex: 0,
        //   isLoading: false
        // },
        // {
        //   type: "ai",
        //   message: [
        //     "星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一星期一"
        //   ],
        //   answerIndex: 0,
        //   isLoading: false
        // }
      ]
      // getToken()
    }
    //上一页
    const preFn = (index: number, answerIndex: number) => {
      if (isLoading.value) return ElMessage.error("正在生成内容,请勿切换。")
      if (answerIndex === 0) {
        chatList.value[index].answerIndex = chatList.value[index].message.length - 1
      } else {
        chatList.value[index].answerIndex = chatList.value[index].answerIndex - 1
      }
    }
    //下一页
    const nextFn = (index: number, answerIndex: number) => {
      if (isLoading.value) return ElMessage.error("正在生成内容,请勿切换。")
      if (answerIndex === chatList.value[index].message.length - 1) {
        chatList.value[index].answerIndex = 0
      } else {
        chatList.value[index].answerIndex = chatList.value[index].answerIndex + 1
      }
    }
    // 1、新建实例md：
    const md = new MarkdownIt()
    const currentHTML = computed(() => {
      // 先判断存不存在，因为一开始currentPost有可能是undefined，在没有拿回数据的时候。
      if (contentItems.value) {
        // if (contentItems.value.includes("</sy_think>")) {
        //   const arr = contentItems.value.split("</sy_think>")
        //   const thinkStr = `
        //   <h4> 师爷模型深度思考中...</h4>
        //   <div style="color: gray;font-size:14px;padding-left:10px;margin-bottom:10px;line-height:25px;border-left:1px solid #e5e5e5">${arr[0]}</div>
        //  `
        //   return thinkStr + md.render(arr[1])
        // } else {
        //   const thinkStr = `
        //   <h4> 师爷模型深度思考中...</h4>
        //   <div style="color: gray;font-size:14px;padding-left:10px;margin-bottom:10px;line-height:25px;border-left:1px solid #e5e5e5">${contentItems.value}</div>`
        //   return thinkStr
        // }
        return contentItems.value.replace("<sy_think>", "")
      } else {
        return ""
      }
    })
    const currentThinkHTML = computed(() => {
      if (contentItems.value) {
        if (contentItems.value.includes("</sy_think>")) {
          const messageStr = currentHTML.value + ""
          const arr = messageStr.split("</sy_think>")
          return arr[0]
        } else {
          return contentItems.value.replace("<sy_think>", "")
        }
      } else {
        return ""
      }
    })
    const currentAnswerHTML = computed(() => {
      if (contentItems.value) {
        if (contentItems.value.includes("</sy_think>")) {
          const messageStr = currentHTML.value + ""
          const arr = messageStr.split("</sy_think>")
          return md.render(arr[1])
        } else {
          return ""
        }
      } else {
        return ""
      }
    })
    //发送问题调用接口
    const sendFn = () => {
      showList.value = false
      controller.value = new AbortController()
      signal.value = controller.value.signal
      //先判断inputStr有没有值,isRegenerate表示是否重新生成
      const inputStr = isRegenerate.value ? preInputValue.value : inputValue.value
      if (!inputStr) return ElMessage.error("请输入要查询的问题。")
      if (isLoading.value) return ElMessage.error("正在生成内容,请稍后。")
      isLoading.value = true
      if (!isRegenerate.value) {
        //第一次生成
        chatList.value.push({
          type: "user",
          message: [inputStr],
          thinkList: [],
          answerList: [],
          answerIndex: 0,
          isLoading: false,
          showThinkList: []
        })
      }
      loadingStatus.value = true
      const url = `/recheck-web/open/shiye/chat?message=${inputStr}&sessionId=${sessionId.value}`
      fetchEventSource(url, {
        method: "GET",
        headers: {
          "Content-type": "application/json",
          Accept: "text/event-stream"
        },
        signal: signal.value,
        openWhenHidden: true,
        // params: JSON.stringify({ message: inputStr }),
        onopen: (e) => {
          if (e.status === 500) return ElMessage.error("服务器忙，请稍后再试。")
          if (isRegenerate.value) {
            //重新生成
            chatList.value[chatList.value.length - 1].message.push("")
            chatList.value[chatList.value.length - 1].thinkList.push("")
            chatList.value[chatList.value.length - 1].answerList.push("")
            chatList.value[chatList.value.length - 1].showThinkList.push(true)
            chatList.value[chatList.value.length - 1].answerIndex =
              chatList.value[chatList.value.length - 1].message.length - 1
          } else {
            chatList.value.push({
              type: "ai",
              message: [],
              thinkList: [],
              answerList: [],
              answerIndex: 0,
              isLoading: true,
              showThinkList: []
            })
            preInputValue.value = inputValue.value
          }
          chatList.value[chatList.value.length - 1].isLoading = true
          inputValue.value = ""
          isLoading.value = true
          loadingStatus.value = false
        },
        onmessage: (event) => {
          const data = JSON.parse(event.data)
          sessionId.value = data.sessionId
          const newItem = data ? data.content : ""
          contentItems.value = contentItems.value + newItem
          if (data.status !== "end") {
          } else {
            if (isRegenerate.value) {
              //重新生成
              const messageStr = currentHTML.value + ""
              chatList.value[chatList.value.length - 1].message[
                chatList.value[chatList.value.length - 1].message.length - 1
              ] = messageStr
              //将currentHTML分为think和answer两部分
              chatList.value[chatList.value.length - 1].thinkList[
                chatList.value[chatList.value.length - 1].message.length - 1
              ] = currentThinkHTML.value
              chatList.value[chatList.value.length - 1].answerList[
                chatList.value[chatList.value.length - 1].message.length - 1
              ] = currentAnswerHTML.value
              chatList.value[chatList.value.length - 1].showThinkList[
                chatList.value[chatList.value.length - 1].message.length - 1
              ] = true
            } else {
              //第一次生成
              // chatList.value[chatList.value.length - 1].message.push(
              //   md.render(
              //     contentItems.value.replace("<sy_think>", "## thinking \n").replace("</sy_think>", "\n## answer \n")
              //   )
              // )
              const messageStr = currentHTML.value + ""
              chatList.value[chatList.value.length - 1].message.push(messageStr)
              //将currentHTML分为think和answer两部分
              chatList.value[chatList.value.length - 1].thinkList.push(currentThinkHTML.value)
              chatList.value[chatList.value.length - 1].answerList.push(currentAnswerHTML.value)
              chatList.value[chatList.value.length - 1].showThinkList.push(true)
            }
          }
          nextTick(() => {
            if (isRolling.value === false) {
              chatContainerRef.value.scrollTop = chatContainerRef.value.scrollHeight
              isRolling.value = false
            }
            if (isBottom.value) {
              isRolling.value = false
              chatContainerRef.value.scrollTop = chatContainerRef.value.scrollHeight
            }
          })
        },
        onclose: () => {
          isLoading.value = false
          loadingStatus.value = false
          chatList.value[chatList.value.length - 1].isLoading = false
          contentItems.value = ""
        },
        onerror: () => {
          isLoading.value = false
          loadingStatus.value = false
          chatList.value[chatList.value.length - 1].isLoading = false
          contentItems.value = ""
        }
      })
    }
    //停止生成
    const stopFn = () => {
      isLoading.value = false
      loadingStatus.value = false
      controller.value.abort()
      //chatList最后一项
      const lastChatItem = chatList.value[chatList.value.length - 1]
      if (isRegenerate.value) {
        lastChatItem.message[lastChatItem.message.length - 1] =
          currentHTML.value + "<div style='font-size:16px;margin-top:10px'>停止生成</div>"
        lastChatItem.thinkList[lastChatItem.message.length - 1] = currentThinkHTML.value
        lastChatItem.answerList[lastChatItem.message.length - 1] =
          currentAnswerHTML.value + "<div style='font-size:16px;margin-top:10px'>停止生成</div>"
        lastChatItem.showThinkList[lastChatItem.message.length - 1] = true
      } else {
        lastChatItem.message.push(currentHTML.value + "<div style='font-size:16px;margin-top:10px'>停止生成</div>")
        lastChatItem.thinkList.push(currentThinkHTML.value)
        lastChatItem.answerList.push(
          currentAnswerHTML.value + "<div style='font-size:16px;margin-top:10px'>停止生成</div>"
        )
        lastChatItem.showThinkList.push(true)
      }
      contentItems.value = ""
      lastChatItem.isLoading = false
    }
    //重新生成
    const regenerateFn = () => {
      isRegenerate.value = true
      sendFn()
    }
    //发送
    const inputBlurFn = (event: any) => {
      emitter.emit("custom-event", { data: true })
      if (!event.ctrlKey) {
        // 如果没有按下组合键ctrl，则会阻止默认事件
        event.preventDefault()
        isRegenerate.value = false
        sendFn()
      } else {
        // 如果同时按下ctrl+回车键，则会换行
        inputValue.value += "\n"
      }
    }
    //复制功能
    const copyFn = (index: number, answerIndex: number) => {
      copyIndex.value = index
      copyText.value = htmlToText(chatList.value[index].message[answerIndex])
      const clipboard = new Clipboard(".copy")
      // 成功
      clipboard.on("success", function (e) {
        ElMessage.success("复制成功")
        e.clearSelection()
        // 释放内存
        clipboard.destroy()
      })
      // 失败
      clipboard.on("error", function (e) {
        ElMessage.error("复制失败")
        clipboard.destroy()
      })
    }
    //试问
    const askFn = (question: string) => {
      inputValue.value = question
      isRegenerate.value = false
      sendFn()
    }
    //滚动事件
    const scrollEvent = (e: any) => {
      //如果滚动到底部,显示向上滚动按钮
      //如果滚动到顶部,显示向下滚动按钮
      const scrollTop = e.target.scrollTop
      const scrollHeight = e.target.scrollHeight
      const offsetHeight = Math.ceil(e.target.getBoundingClientRect().height)
      const currentHeight = scrollTop + offsetHeight
      if (currentHeight >= scrollHeight) {
        scrollTopShow.value = true
        isBottom.value = true
      } else {
        isBottom.value = false
        scrollTopShow.value = false
      }

      if (scrollHeight > offsetHeight) {
        scrollBottomShow.value = true
      } else {
        scrollBottomShow.value = false
      }
    }
    //向上滚动
    const scrollTopFn = () => {
      chatContainerRef.value.scrollTop = 0
    }
    //向下滚动
    const scrollBottomFn = () => {
      chatContainerRef.value.scrollTop = chatContainerRef.value.scrollHeight + 250
    }
    const viewDialogRef = ref()
    const viewFn = () => {
      viewDialogRef.value.dialogVisible = true
    }
    watch(
      () => chatList.value,
      () => {
        if (chatList.value && chatList.value.length > 0) {
          chatContainerRef.value.scrollTop = chatContainerRef.value.scrollHeight + 250
        }
      },
      { deep: true }
    )
    onUnmounted(() => {
      if (isLoading.value) {
        isLoading.value = false
        loadingStatus.value = false
        controller.value.abort()
      }
    })
    return {
      inputValue,
      isLoading,
      chatList,
      preFn,
      nextFn,
      sendFn,
      contentItems,
      stopFn,
      preInputValue,
      currentHTML,
      chatContainerRef,
      regenerateFn,
      inputBlurFn,
      copyFn,
      copyText,
      questionList,
      askFn,
      loadingStatus,
      copyIndex,
      showList,
      scrollTopShow,
      scrollBottomShow,
      scrollEvent,
      scrollTopFn,
      scrollBottomFn,
      viewFn,
      viewDialogRef,
      currentThinkHTML,
      currentAnswerHTML,
      showThinkFn,
      hideThinkFn
    }
  }
})
